﻿using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Browser;

namespace Refract
{
    /// <summary>
    /// Base class for all Refract classes, implements notification change and provides utility functionality
    /// </summary>
    public abstract class Component : INotifyPropertyChanged
    {
        #region Properties

        /// <summary>
        /// Gets or sets the dispatcher.
        /// </summary>
        /// <value>The dispatcher.</value>
        public Dispatcher Dispatcher { get; private set; }


        /// <summary>
        /// Gets a value indicating whether the app is running in design mode.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this app is in design mode; otherwise, <c>false</c>.
        /// </value>
        public bool IsDesignMode
        {
            get
            {
                return HtmlPage.IsEnabled == false;
            }
        }
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Component"/> class.
        /// </summary>
        public Component()
        {
            if (Application.Current != null)
            {
                Dispatcher = Deployment.Current.Dispatcher;
            }
        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Raises the property changed event.
        /// </summary>
        /// <param name="propertyName">Name of the property that changed.</param>
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                if (Dispatcher != null && !Dispatcher.CheckAccess())
                {
                    Dispatcher.BeginInvoke((ThreadStart)delegate()
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    });
                }
                else
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }                
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }    
}

